package cn.jy.generate.enums;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Arrays;
import java.util.List;

/**
 * 多条件查询字典.
 *
 * <p>
 *     Bean Searcher 多条件查询参数字典
 *     https://bs.zhxu.cn/guide/latest/params.html#%E5%AD%97%E6%AE%B5%E8%BF%90%E7%AE%97%E7%AC%A6
 * </p>
 *
 *  Equal        	eq x = ?                             			是  等于（是缺省默认的运算符）
 *  NotEqual     	ne x != ?                            			是  不等于
 *  GreaterThan  	gt x > ?                             			是  大于
 *  GreaterEqual 	ge x >= ?                            			是  大于等于
 *  LessThan     	lt x < ?                             			是  小于
 *  LessEqual    	le x <= ?                            			是  小于等于
 *  Between      	bt x between ?1 and ?2 / x >= ?1 / x <= ?2     	是  在...之间（范围查询）
 *  NotBetween   	nb x not between ?1 and ?2 / x < ?1 / x > ?2  	是  不在...之间（范围查询）
 *  Contain      	ct x like '%?%'                        			是  包含（模糊查询）
 *  StartWith    	sw x like '?%'                            		是  以...开头（模糊查询）
 *  EndWith     	ew x like '%?'                            		是  以...结尾（模糊查询）
 *  OrLike      	ol x like ?1 or x like ?2 or ...           		是  模糊或匹配（可有多个参数值）
 *  NotLike     	nk x not like ?                        			是  反模糊匹配
 *  InList      	il x in (?, ?, ...)                     		是  多值查询
 *  NotIn       	ni x not in (?, ?, ...)                  		是  多值查询
 *  IsNull      	nl x is null                          			否  为空
 *  NotNull     	nn x is not null                       			否  不为空
 *  Empty       	ey x is null or x = ''                      	否  为空（仅适用于 字符串 类型的字段）
 *  NotEmpty    	ny x is not null and x != ''              		否  不为空（仅适用于 字符串 类型的字段）
 *
 * @author ljw
 **/
@Getter
@AllArgsConstructor
public enum MultiConditionQueryConditionEnum {

	EQUAL("eq", "等于", "x = ?"),
	NOT_EQUAL("ne", "不等于", "x != ?"),
	GREATER_THAN("gt", "大于", "x > ?"),
	GREATER_EQUAL("ge", "大于等于", "x >= ?"),
	LESS_THAN("lt", "小于", "x < ?"),
	LESS_EQUAL("le", "小于等于", "x <= ?"),
	BETWEEN("bt", "在...之间", "x between ?1 and ?2"),
	NOT_BETWEEN("nb", "不在...之间", "x not between ?1 and ?2"),
	CONTAIN("ct", "包含", "x like '%?%'"),
	START_WITH("sw", "以...开头", "x like '?%'"),
	END_WITH("ew", "以...结尾", "x like '%?'"),
	OR_LIKE("ol", "模糊或匹配", "x like ?1 or x like ?2"),
	NOT_LIKE("nk", "反模糊匹配", "x not like ?"),
	IN_LIST("il", "多值查询", "x in (?)"),
	NOT_IN("ni", "多值查询", "x not in (?)"),
	IS_NULL("nl", "为空", "x is null"),
	NOT_NULL("nn", "不为空", "x is not null"),
	EMPTY("ey", "为空", "x is null or x = ''"),
	NOT_EMPTY("ny", "不为空", "x is not null and x != ''");

	private final String code;
	private final String name;
	private final String symbol;

	public static String TABLE_COLUMN = "x";
	public static String TABLE_VALUE = "?";
	public static String TABLE_VALUE1 = "?1";
	public static String TABLE_VALUE2 = "?2";
	public static String TABLE_VALUE_FORMAT = "'%s'";


	/**
	 * 获取字符串类型的多条件查询条件。
	 *
	 * @return
	 */
	public static List<MultiConditionQueryConditionEnum> getStringTypeCondition() {
		return Arrays.asList(
			EQUAL, NOT_EQUAL, CONTAIN, START_WITH, END_WITH, OR_LIKE, NOT_LIKE, IN_LIST, NOT_IN, EMPTY, NOT_EMPTY);
	}

	/**
	 * 获取日期类型的多条件查询条件。
	 *
	 * @return
	 */
	public static List<MultiConditionQueryConditionEnum> getDateTypeCondition() {
		return Arrays.asList(
			EQUAL, NOT_EQUAL, GREATER_THAN, GREATER_EQUAL, LESS_THAN, LESS_EQUAL, IS_NULL, NOT_NULL);
	}

	/**
	 * 获取数据类型的多条件查询条件。
	 *
	 * @return
	 */
	public static List<MultiConditionQueryConditionEnum> getNumberTypeCondition() {
		return Arrays.asList(
			EQUAL, NOT_EQUAL, GREATER_THAN, GREATER_EQUAL, LESS_THAN, LESS_EQUAL, IS_NULL, NOT_NULL);
	}

	/**
	 * 获取Boolean类型的多条件查询条件。
	 *
	 * @return
	 */
	public static List<MultiConditionQueryConditionEnum> getBooleanTypeCondition() {
		return Arrays.asList(EQUAL, NOT_EQUAL, IS_NULL, NOT_NULL);
	}

	/**
	 * 数据库字段类型转java类型.
	 *
	 * @param dbColumnType 数据库类型
	 * @return java类型
	 */
	public static List<MultiConditionQueryConditionEnum> getConditionByType(String dbColumnType) {
		if (dbColumnType == null) {
			return null;
		}
		dbColumnType = dbColumnType.toLowerCase();
		if (dbColumnType.contains("char") || dbColumnType.contains("text")) {
			return getStringTypeCondition();
		} else if (dbColumnType.contains("bigint") || dbColumnType.contains("long")) {
			return getNumberTypeCondition();
		} else if (dbColumnType.contains("int")) {
			return getNumberTypeCondition();
		} else if (dbColumnType.contains("date") || dbColumnType.contains("time") || dbColumnType.contains("year")) {
			return getDateTypeCondition();
		} else if (dbColumnType.contains("text")) {
			return getStringTypeCondition();
		} else if (dbColumnType.contains("bit")) {
			return getBooleanTypeCondition();
		} else if (dbColumnType.contains("decimal")) {
			return getNumberTypeCondition();
		} else if (dbColumnType.contains("blob")) {
			return getStringTypeCondition();
		} else if (dbColumnType.contains("float")) {
			return getNumberTypeCondition();
		} else if (dbColumnType.contains("double")) {
			return getNumberTypeCondition();
		} else if (dbColumnType.contains("json") || dbColumnType.contains("enum")) {
			return getStringTypeCondition();
		}
		return getStringTypeCondition();
	}


}
